#include "head.h"

uint8_t WHGM5_RxCommand;
uint8_t pWHGM5_RxParameter[WHGM5_RxParameter_Length];
uint8_t WHGM5_RxParameterCount;
int8_t WHGM5_UARTresult;

uint8_t pSpectrometerAndGpsBuff[4096+ATGM336H_GPS_Buffer_Length];

uint8_t *pFPGA_Spectrometer = pSpectrometerAndGpsBuff;
uint8_t FPGA_RxCommand;
uint8_t FPGA_RxParameter[FPGA_RxParameter_Length];
uint8_t FPGA_RxParameterCount;
int8_t FPGA_UARTresult;

uint8_t *pATGM336H_GPS = &pSpectrometerAndGpsBuff[4096];
uint16_t ATGM336H_GPSdataCount;

uint8_t pRS232RxBuff[128];
uint8_t RS232RxBuffCount;

uint16_t pICM_Accel[3];

uint16_t pBAT2U_Buff[2];

uint16_t vbat_Voltage;

uint8_t battery_Voltage;

uint8_t isLeaveWater;

uint8_t isFPGA_SpectrometerContinuousSend=0;

bool isHalfSleep = 0;//半休眠标志位

/**
 * main.c
 */
void main(void)
{
    //------------------配置时钟频率等---------------
    msp430_Init();
    //---------------初始化掉电保存结构体-------------
    PDS_InitStrPDS();
    //----------------初始化各模块----------------
    FPGA_Init();
    printfDBG("GPS",3);
    ATGM336H_Init();
    printfDBG("4G",2);
    WHGM5_Init('A',0,"hywater.hytech.top","8453");
    WHGM5_Init('B',0,"zkpg.cas-hytech.com","8686");
    printfDBG("BAT2",4);
    BAT2U_Init();
    printfDBG("TPL",3);
    TPL_IIC_Init();
    printfDBG("lWater",6);
    lwater_Init();
    printfDBG("vbat",4);
    vbat_Init();
    printfDBG("battery",7);
    battery_Init();
    printfDBG("ICM",3);
    ICM_IIC_Init();
    printfDBG("Init finish",11);
    //-----------各个模块初始化完毕，使能掉电保存的设置--------
    main_enablePDS();
    //----------初始化到这里结束，算是开机完毕--------

    Timer_InitTimer();
    uint8_t cmd25=0x25;
    main_sendCmd(&cmd25,4,(uint8_t *)&strPDS.msp430ID,0,0);
#ifndef __DEBUG //如果没有处于调试模式，开启看门狗
    WDT_A_start(WDT_A_BASE);
#endif

    while(1)
    {
#ifndef __DEBUG//如果没有处于调试模式，开启看门狗
        WDT_A_resetTimer(WDT_A_BASE);//重置看门狗计时器，喂狗
#endif
        FPGA_UARTresult = FPGA_parseUSB_Buffer(&FPGA_RxCommand,FPGA_RxParameter,&FPGA_RxParameterCount);
        if(FPGA_UARTresult)
        {
            if(FPGA_UARTresult == 1)//接到了指令
            {
                printfDBG("Get command from USB",20);
                main_PareRx(FPGA_RxCommand,FPGA_RxParameter,FPGA_RxParameterCount,FPGA_USCI_BASE);
            }
            else if(FPGA_UARTresult == -1)//校验和匹配失败
            {
                FPGA_sendStrLen("CRC false",9);
            }
            FPGA_UARTresult = 0;
        }
        WHGM5_UARTresult = WHGM5_parse4GBuffer(&WHGM5_RxCommand,pWHGM5_RxParameter,&WHGM5_RxParameterCount);
        if(WHGM5_UARTresult)
        {
            if(WHGM5_UARTresult == 1)//接到了指令
            {
                printfDBG("Get command from 4G",19);
                main_PareRx(WHGM5_RxCommand,pWHGM5_RxParameter,WHGM5_RxParameterCount,WHGM5_USCI_BASE);
            }
            else if(WHGM5_UARTresult == -1)//校验和匹配失败
            {
                WHGM5_sendStr("CRC false\n");
            }
            WHGM5_UARTresult = 0;
        }
        if(isFPGA_SpectrometerContinuousSend == 1)
        {
            uint8_t cmd = 0x10;
            FPGA_ReceiveSpectrometer(pFPGA_Spectrometer);
            ATGM336H_getRMC(pATGM336H_GPS,&ATGM336H_GPSdataCount);
            main_sendCmd(&cmd,ATGM336H_GPSdataCount+4096,pSpectrometerAndGpsBuff,0,0);
        }
        main_alarmClock();
    }
}

void main_sendStrLen(uint8_t *data,uint16_t dataLen,uint8_t dataDir,uint8_t *crc)
{
    uint16_t i;
    if(dataDir)//高位在低端
    {
        for(i= dataLen-1;i != 0xffff;i--)
        {
            *crc += data[i];//计算校验和
            USCI_A_UART_transmitData(WHGM5_USCI_BASE,data[i]);//发送字节
        }
    }
    else//高位在高端
    {
        for(i=0;i<dataLen;i++)
        {
            *crc += data[i];
            USCI_A_UART_transmitData(WHGM5_USCI_BASE,data[i]);
        }
    }
}

void main_sendCmd(uint8_t *TxCommand,uint16_t TxParameterLen,uint8_t *TxParameter,uint8_t TxParameterDir,uint16_t uartBaseAddress)
{
    uint16_t i;
    uint8_t j;
    /*
     * 计算校验和
     */
    uint8_t crc=0x21;//0x55+0xcc = 0x121
    uint16_t cmdLen = TxParameterLen+8;//命令长度=参数长度+8
    crc += (uint8_t)(cmdLen >> 8);
    crc += (uint8_t)cmdLen;
    crc += *TxCommand;
    for(i = 0;i < TxParameterLen;i++)
    {
        crc += TxParameter[i];
    }
    /*
     * 发命令
     */
    if(uartBaseAddress == 0)
    {
#ifdef __DEBUG
        for(j = 0;j < 1;j++) //仅仅将报文输出到4G
#else
        for(j = 0;j < 2;j++) //将报文同时输出到4G与USB
#endif
        {
            if(j==0)
            {
                printfDBG("Send data to 4G",15);
                uartBaseAddress = WHGM5_USCI_BASE;
            }
            else
            {
                printfDBG("Send data to USB",16);
                uartBaseAddress = FPGA_USCI_BASE;
            }
            //----------------------------55cc----------------------------
            USCI_A_UART_transmitData(uartBaseAddress,0x55);
            USCI_A_UART_transmitData(uartBaseAddress,0xcc);
            //---------------------------命令长度-----------------------------
            USCI_A_UART_transmitData(uartBaseAddress,(uint8_t)cmdLen);//命令长度是MSB，高位在低端，所以这里反过来
            USCI_A_UART_transmitData(uartBaseAddress,(uint8_t)(cmdLen >> 8));
            //-----------------------------命令-----------------------------
            USCI_A_UART_transmitData(uartBaseAddress,*TxCommand);
            //-----------------------------参数-----------------------------
            if(TxParameterLen>=4096)//判断是否是光谱仪数据
            {
                uint8_t greaterCountHight = 0;
                uint8_t greaterCountLow = 0;
                uint16_t k;
                for(k=0+1200;k<9+1200;k++)//从第1200个数开始，取前9个数高(低)位与下一个高(低)位比较是否相等并计数
                {
                    if((TxParameter[2*k+0] == TxParameter[2*k+2])  ||
                       (TxParameter[2*k+0] == TxParameter[2*k+2]+1)||
                       (TxParameter[2*k+0] == TxParameter[2*k+2]-1))
                    {
                        greaterCountHight += 1;//高位比较计数
                    }
                    if((TxParameter[2*k+1] == TxParameter[2*k+3])  ||
                       (TxParameter[2*k+1] == TxParameter[2*k+3]+1)||
                       (TxParameter[2*k+1] == TxParameter[2*k+3]-1))
                    {
                        greaterCountLow += 1;//低位比较计数
                    }
                }
                if(greaterCountHight > greaterCountLow)//计数多的那个更大概率是高位，如果High是高位，则需要调换顺序发送
                {
                    for(k = 0; k < 2048;k++)//调换顺序发送光谱仪数据
                    {
                        USCI_A_UART_transmitData(uartBaseAddress,TxParameter[2*k+1]);
                        USCI_A_UART_transmitData(uartBaseAddress,TxParameter[2*k]);
                    }
                }
                else
                {
                    for(k = 0; k < 4096;k++)//不调换顺序发送光谱仪数据
                    {
                        USCI_A_UART_transmitData(uartBaseAddress,TxParameter[k]);
                    }
                }
                for(i = 4096;i < TxParameterLen;i++)//把剩下的GPS部分发送
                {
                    USCI_A_UART_transmitData(uartBaseAddress,TxParameter[i]);
                }
            }
            else if(TxParameterDir == 0)//LSB高位在高端
            {
                for(i = 0;i < TxParameterLen;i++)
                {
                    USCI_A_UART_transmitData(uartBaseAddress,TxParameter[i]);
                }
            }
            else//MSB高位在低端
            {
                for(i = TxParameterLen - 1;i != 65535;i--)
                {
                    USCI_A_UART_transmitData(uartBaseAddress,TxParameter[i]);
                }
            }

            //----------------------------命令尾部----------------------------
            USCI_A_UART_transmitData(uartBaseAddress,crc);
            USCI_A_UART_transmitData(uartBaseAddress,0x00);
            USCI_A_UART_transmitData(uartBaseAddress,0x00);
        }
    }
    else
    {
        //----------------------------55cc----------------------------
        USCI_A_UART_transmitData(uartBaseAddress,0x55);
        USCI_A_UART_transmitData(uartBaseAddress,0xcc);
        //---------------------------命令长度-----------------------------
        USCI_A_UART_transmitData(uartBaseAddress,(uint8_t)cmdLen);//命令长度是MSB，高位在低端，所以这里反过来
        USCI_A_UART_transmitData(uartBaseAddress,(uint8_t)(cmdLen >> 8));
        //-----------------------------命令-----------------------------
        USCI_A_UART_transmitData(uartBaseAddress,*TxCommand);
        //-----------------------------参数-----------------------------
        if(TxParameterLen>=4096)//判断是否是光谱仪数据
        {
            uint8_t greaterCountHight = 0;
            uint8_t greaterCountLow = 0;
            uint16_t k;
            for(k=0+1200;k<9+1200;k++)//从第1200个数开始，取前9个数高(低)位与下一个高(低)位比较是否相等并计数
            {
                if((TxParameter[2*k+0] == TxParameter[2*k+2])  ||
                   (TxParameter[2*k+0] == TxParameter[2*k+2]+1)||
                   (TxParameter[2*k+0] == TxParameter[2*k+2]-1))
                {
                    greaterCountHight += 1;//高位比较计数
                }
                if((TxParameter[2*k+1] == TxParameter[2*k+3])  ||
                   (TxParameter[2*k+1] == TxParameter[2*k+3]+1)||
                   (TxParameter[2*k+1] == TxParameter[2*k+3]-1))
                {
                    greaterCountLow += 1;//低位比较计数
                }
            }
            if(greaterCountHight > greaterCountLow)//计数多的那个更大概率是高位，如果High是高位，则需要调换顺序发送
            {
                for(k = 0; k < 2048;k++)//调换顺序发送光谱仪数据
                {
                    USCI_A_UART_transmitData(uartBaseAddress,TxParameter[2*k+1]);
                    USCI_A_UART_transmitData(uartBaseAddress,TxParameter[2*k]);
                }
            }
            else
            {
                for(k = 0; k < 4096;k++)//不调换顺序发送光谱仪数据
                {
                    USCI_A_UART_transmitData(uartBaseAddress,TxParameter[k]);
                }
            }
            for(i = 4096;i < TxParameterLen;i++)//把剩下的GPS部分发送
            {
                USCI_A_UART_transmitData(uartBaseAddress,TxParameter[i]);
            }
        }
        else if(TxParameterDir == 0)//LSB高位在高端
        {
            for(i = 0;i < TxParameterLen;i++)
            {
                USCI_A_UART_transmitData(uartBaseAddress,TxParameter[i]);
            }
        }
        else//MSB高位在低端
        {
            for(i = TxParameterLen - 1;i != 65535;i--)
            {
                USCI_A_UART_transmitData(uartBaseAddress,TxParameter[i]);
            }
        }

        //----------------------------命令尾部----------------------------
        USCI_A_UART_transmitData(uartBaseAddress,crc);
        USCI_A_UART_transmitData(uartBaseAddress,0x00);
        USCI_A_UART_transmitData(uartBaseAddress,0x00);
    }
}

void main_enablePDS()
{
    uint8_t cmd;
    //发送增益设置命令给fpga
    cmd = 0x14;
    main_sendCmd(&cmd,2,(uint8_t *)&strPDS.gain,0,FPGA_USCI_BASE);
    __delay_cycles(MSP430_FREQUENCY/100);

    //发送偏压设置命令给fpga
    cmd = 0x15;
    main_sendCmd(&cmd,2,(uint8_t *)&strPDS.bias,0,FPGA_USCI_BASE);
    __delay_cycles(MSP430_FREQUENCY/100);

    //发送可见光积分设置命令给fpga
    cmd = 0x11;
    main_sendCmd(&cmd,4,(uint8_t *)&strPDS.visibleIntegral,0,FPGA_USCI_BASE);
    __delay_cycles(MSP430_FREQUENCY/100);

    //设置补光灯电压
    float value = ((float)strPDS.lightVoltage) / 10.0;
    TPL_SetValueD(value);
    //设置定时发送的下次一发送时间
    Timer_startTiming(&TimerInfoSend,(uint16_t)strPDS.infoSendTime * 60);
}

void main_PareRx(uint8_t RxCommand,uint8_t *RxParameter,uint8_t RxParameterCount,uint16_t uartBaseAddress)
{
    //-------------------------半休眠---------------------------
    if(isHalfSleep == 1)//如果处于半休眠状态
    {
        if(RxCommand == 0x41)//半休眠相关命令
        {
            if(RxParameter[0] == 0x00)
	    {//退出半休眠状态
                isHalfSleep = 0;
                msp430_HalfSleep_Exit();
                printfDBG("battery",7);
                battery_Init();
                printfDBG("ATGM336H",8);
                ATGM336H_Init();
                printfDBG("ICM",3);
                ICM_IIC_Init();
                main_sendCmd(&RxCommand,RxParameterCount,RxParameter,0,0);//20210802
            }
        }
        return;
    }
    else if(isHalfSleep == 0)//如果不处于半休眠状态
    {
        if(RxCommand == 0x41)//半休眠相关命令
        {
            if(RxParameter[0] == 0x01)
	    {//进入半休眠状态
                isHalfSleep = 1;
                msp430_HalfSleep_Enter();
                main_sendCmd(&RxCommand,RxParameterCount,RxParameter,0,0);//20210802
            }
        }
    }

    //--------------------------光谱仪采集命令--------------------------
    if(RxCommand == 0x10)
    {
        if(RxParameter[0] == 0x00){//停止采集光谱仪
            isFPGA_SpectrometerContinuousSend = 0;
        }
        else if(RxParameter[0] == 0x01){//连续采集光谱仪
            isFPGA_SpectrometerContinuousSend = 1;
        }
        else if(RxParameter[0] == 0x05){//定时单次采集
            isFPGA_SpectrometerContinuousSend = 2;
        }
        else{//单次采集光谱仪
            uint8_t cmd = 0x6e + RxParameter[0];
            FPGA_ReceiveSpectrometer(pFPGA_Spectrometer);
            ATGM336H_getRMC(pATGM336H_GPS,&ATGM336H_GPSdataCount);
            main_sendCmd(&cmd,ATGM336H_GPSdataCount+4096,pSpectrometerAndGpsBuff,0,0);
        }
    }
    //--------------------------光谱仪开灯采集命令--------------------------
    if(RxCommand == 0x81)
    {
        printfDBG("0x81:Open light",15);
        msp430_TPL_powerOutON();
        __delay_cycles(MSP430_FREQUENCY);
        if(RxParameter[0] == 0x00){//停止采集光谱仪
            printfDBG("0x81:00",7);
            isFPGA_SpectrometerContinuousSend = 0;
        }
        else if(RxParameter[0] == 0x01){//连续采集光谱仪
            printfDBG("0x81:01",7);
            isFPGA_SpectrometerContinuousSend = 1;
        }
        else if(RxParameter[0] == 0x05){//定时单次采集
            printfDBG("0x81:05",7);
            isFPGA_SpectrometerContinuousSend = 2;
        }
        else{//单次采集光谱仪
            printfDBG("0x81:Single collect",19);
            uint8_t cmd = 0x6e + RxParameter[0];
            FPGA_ReceiveSpectrometer(pFPGA_Spectrometer);
            ATGM336H_getRMC(pATGM336H_GPS,&ATGM336H_GPSdataCount);
            main_sendCmd(&cmd,ATGM336H_GPSdataCount+4096,pSpectrometerAndGpsBuff,0,0);
        }
        printfDBG("0x81:Close light",8);
        msp430_TPL_powerOutOFF();
    }
    //------------------------光谱仪设置曝光时间命令------------------------
    else if(RxCommand == 0x11)
    {
        printfDBG("0X11start",9);
    #if 1
        if(RxParameterCount == 1)//1一个字节长度的积分时间，可见光与短波同步修改
        {
            printfDBG("0X11:1",6);
            strPDS.visibleIntegral =  (uint32_t)RxParameter[0];
            strPDS.shortwaveIntegral = (uint32_t)RxParameter[0];
            main_sendCmd(&RxCommand,RxParameterCount,RxParameter,0,0);//20210802
        }
        else if(RxParameterCount == 2)//2个字节分别设置可见光与短波积分
        {
            printfDBG("0X11:2",6);
            strPDS.visibleIntegral =  (uint32_t)RxParameter[0];
            strPDS.shortwaveIntegral = (uint32_t)RxParameter[1];
            main_sendCmd(&RxCommand,RxParameterCount,RxParameter,0,0);//20210802
        }
    #else//4个字节长度的积分时间
        strPDS.visibleIntegral =  (((uint32_t)RxParameter[3])<<24) |
                                    (((uint32_t)RxParameter[2])<<16) |
                                    (((uint32_t)RxParameter[1])<<8)  |
                                    (((uint32_t)RxParameter[0])<<0);
        main_sendCmd(&RxCommand,RxParameterCount,RxParameter,0,FPGA_USCI_BASE);
    #endif
        printfDBG("0X11end",7);
    }
    //------------------------光谱仪设置增益时间命令------------------------
    else if(RxCommand == 0x14)
    {
        strPDS.gain = (((uint16_t)RxParameter[1])<<8)|
                        (((uint16_t)RxParameter[0]));
        main_sendCmd(&RxCommand,RxParameterCount,RxParameter,0,0);//20210802
    }
    //------------------------光谱仪设置曝光偏压命令------------------------
    else if(RxCommand == 0x15)
    {
        strPDS.bias = (((uint16_t)RxParameter[1])<<8)|
                        (((uint16_t)RxParameter[0]));
        main_sendCmd(&RxCommand,RxParameterCount,RxParameter,0,0);//20210802
    }
    //--------------------------光源开关--------------------------
    else if(RxCommand == 0x12)
    {
        if(RxParameter[0] == 0x10){//关闭光源
            msp430_TPL_powerOutOFF();
        }
        else if(RxParameter[0] == 0x11){//打开光源
            msp430_TPL_powerOutON();
        }
        main_sendCmd(&RxCommand,RxParameterCount,RxParameter,0,0);//20210802
    }
    //------------------------电压设置TPL------------------------
    else if(RxCommand == 0x22)
    {
        strPDS.lightVoltage = (((uint16_t)RxParameter[1])<<8)|
                                (((uint16_t)RxParameter[0]));

        float value = ((float)strPDS.lightVoltage) / 10.0;
        TPL_SetValueD(value);
        main_sendCmd(&RxCommand,RxParameterCount,RxParameter,0,0);//20210802
    }
    //-------------------------设置低功耗模式---------------------------
    else if(RxCommand == 0x37)
    {
        //------------------保存信息到结构体--------------------
        strPDS.lowPowerEnable = RxParameter[0];
        strPDS.lowPowerSleep = RxParameter[1];
        strPDS.lowPowerThreshold = (((uint16_t)RxParameter[2]))|
                                    (((uint16_t)RxParameter[3])<<8);
        strPDS.lowPoewrCheackInterval = (((uint16_t)RxParameter[4]))|
                                        (((uint16_t)RxParameter[5])<<8);
        strPDS.lowPowerSleepInterval = RxParameter[6];
        //-----------------检查参数有无异常----------------------
        if(strPDS.lowPowerSleep < 1)
        {
            strPDS.lowPowerSleep = 1;
        }
        else if(strPDS.lowPowerSleep > 120)
        {
            strPDS.lowPowerSleep = 120;
        }

        if(strPDS.lowPowerSleepInterval < 1)
        {
            strPDS.lowPowerSleepInterval = 1;
        }
        else if(strPDS.lowPowerSleepInterval > 120)
        {
            strPDS.lowPowerSleepInterval = 120;
        }
        //-------------让电源检查程序在下一秒开始运行----------------
        Timer_startTiming(&TimerVbatCheck,1);
        main_sendCmd(&RxCommand,RxParameterCount,RxParameter,0,FPGA_USCI_BASE);//20210802
    }
    //-------------------------设置定时发送功能---------------------------
    else if(RxCommand == 0x40)
    {
        //-----------------保存信息到结构体----------------------
        strPDS.infoSendTime = RxParameter[0];
        strPDS.infoSendDetail = RxParameter[1];
        //-----------------改变定时发送信息的状态-------------------
        if(strPDS.infoSendTime == 0)//如果为0
        {
            Timer_closeTiming(&TimerInfoSend);
        }
        else//不为0
        {
            Timer_startTiming(&TimerInfoSend,1);//在1秒后发送一个信息
        }
        main_sendCmd(&RxCommand,RxParameterCount,RxParameter,0,0);//20210802
    }
    //-------------------------电磁锁开关-------------------------
    else if(RxCommand == 0x35)
    {
        if(RxParameter[0] == 0x10){//关闭电磁锁
            GPIO_setOutputLowOnPin(ELE_LOCK_PORT,ELE_LOCK_PIN);
        }
        else if(RxParameter[0] == 0x11){//打开电磁锁
            GPIO_setOutputHighOnPin(ELE_LOCK_PORT,ELE_LOCK_PIN);
            if(RxParameter[1]!=0)//计时功能
            {
                Timer_startTiming(&TimerEleLock,RxParameter[1]);
            }
        }
        main_sendCmd(&RxCommand,RxParameterCount,RxParameter,0,0);//20210812
    }
    //-------------------------获取设备信息-------------------------
    else if(RxCommand == 0x20)
    {
        main_sendCmd(&RxCommand,PDS_LEN,(uint8_t *)&strPDS,0,0);
    }
    //--------------------将掉电保留设置写进flash-----------------------
    else if(RxCommand == 0x05)
    {
        if((RxParameter[0] == 0x17) && (RxParameter[1] == 0x20))
        {
            PDS_WriteStrPDS(&strPDS);
            main_enablePDS();
            main_sendCmd(&RxCommand,RxParameterCount,RxParameter,0,0);//20210804
        }
    }
    //-------------------------获取水质信息-------------------------
    else if(RxCommand == 0x31)
    {
        BAT2U_SenseCommand(&pBAT2U_Buff[1], &pBAT2U_Buff[0]);
        main_sendCmd(&RxCommand,4,(uint8_t *)pBAT2U_Buff,1,0);
    }
    //-------------------------获取离水状态--------------------------
    else if(RxCommand == 0x30)
    {
        lwater_isLeave(&isLeaveWater);
        main_sendCmd(&RxCommand,1,&isLeaveWater,1,0);
    }
    //-----------------------获取电源电压vbat------------------------
    else if(RxCommand == 0x32)
    {
        vbat_GetVoltage(&vbat_Voltage);
        main_sendCmd(&RxCommand,2,(uint8_t *)&vbat_Voltage,1,0);
    }
    //----------------------获取电池电压battery------------------------
    else if(RxCommand == 0x21)
    {
        battery_getVoltage(&battery_Voltage);
        main_sendCmd(&RxCommand,1,&battery_Voltage,1,0);
    }
    //----------------------获取陀螺仪ICM20602------------------------
    else if(RxCommand == 0x33)
    {
        ICM_Get_Accelerometer(&pICM_Accel[0],&pICM_Accel[1],&pICM_Accel[2]);
        main_sendCmd(&RxCommand,6,(uint8_t *)&pICM_Accel,1,0);
    }
    //---------------------获取GPS数据ATGM336H-----------------------
    else if(RxCommand == 0x34)
    {
        ATGM336H_getRMC(pATGM336H_GPS,&ATGM336H_GPSdataCount);
        main_sendCmd(&RxCommand,ATGM336H_GPSdataCount,(uint8_t *)pATGM336H_GPS,0,0);
    }
    //-------------------------获取握手信息---------------------------
    else if(RxCommand == 0x25)
    {
        main_sendCmd(&RxCommand,4,(uint8_t *)&strPDS.msp430ID,0,0);
    }
    //------------------------RS485功能---------------------------
    else if(RxCommand == 0x36)
    {
        FPGA_getRS485(RxParameter,RxParameterCount,pRS232RxBuff,&RS232RxBuffCount,uartBaseAddress);
        main_sendCmd(&RxCommand,RS232RxBuffCount,pRS232RxBuff,0,WHGM5_USCI_BASE);
    }
    //-------------------------调试---------------------------
    else if(RxCommand == 0x77)
    {
        //给4G模块单独重新上电
        GPIO_setOutputLowOnPin(WHGM5_POW_PORT,WHGM5_POW_PIN);
        __delay_cycles(MSP430_FREQUENCY*2);
        GPIO_setOutputHighOnPin(WHGM5_POW_PORT,WHGM5_POW_PIN);
    }
}

void main_alarmClock()
{
//---------------------------------电磁锁定时关闭------------------------------
    if(TimerEleLock.flag & TIMER_STR_SECOND_CHRON_FLAG_RUNING)
    {
        if(Timer_checkoutTiming(&TimerEleLock))//时间到，关闭电磁锁
        {
            printfDBG("ELE Lock close automatic start",30);
            GPIO_setOutputLowOnPin(ELE_LOCK_PORT,ELE_LOCK_PIN);
            printfDBG("ELE Lock close automatic finish",31);
        }
    }
//---------------------------------刷新GPS的LED指示灯状态------------------------------
    if(TimerATGM336Led.flag & TIMER_STR_SECOND_CHRON_FLAG_RUNING && !isHalfSleep)
    {
        if(Timer_checkoutTiming(&TimerATGM336Led))
        {
            printfDBG("GPS LED fresh start",19);
            Timer_startTiming(&TimerATGM336Led,1);//重新计时1秒
            ATGM336H_ledToggle();
            printfDBG("GPS LED fresh finish",20);
        }
    }
//---------------------------------检查GPS模块天线状态------------------------------
    static uint8_t ATGM336H_AntennaStatusLast;
    if(TimerATGM336AntennaCheck.flag & TIMER_STR_SECOND_CHRON_FLAG_RUNING && !isHalfSleep)
    {
        if(Timer_checkoutTiming(&TimerATGM336AntennaCheck))//时间到，检查GPS天线
        {
            Timer_startTiming(&TimerATGM336AntennaCheck,3);//重新计时
            if(ATGM336H_AntennaStatus = ATGM336H_checkStatus(pATGM336H_GPS,&ATGM336H_GPSdataCount))//不等于零则天线不正常
            {//没能接到正常数据
                if(ATGM336H_AntennaStatus == 1)
                {//天线OK
                    ATGM336H_ledON();
                }
                else if((ATGM336H_AntennaStatus == 2) || (ATGM336H_AntennaStatus == 3))
                {//天线不OK
                    ATGM336H_ledOFF();
                }
                else
                {
                    printfDBG("GPS antenna status check return 4",33);
                }
                Timer_closeTiming(&TimerATGM336Led);
            }
            else if(ATGM336H_AntennaStatusLast != 0)//接收到正常数据
            {//且上次没有接收到正常数据，第一次转换状态
                Timer_startTiming(&TimerATGM336Led,1);//开启
            }
            ATGM336H_AntennaStatusLast = ATGM336H_AntennaStatus;
//            printfDBG("GPS antenna status check finish",30);
        }
    }
//-----------------------------------定时发送信息--------------------------------
    uint16_t pareCount=0;
    uint8_t crc;
    if(TimerInfoSend.flag & TIMER_STR_SECOND_CHRON_FLAG_RUNING)//定时发送开启
    {

        if(Timer_checkoutTiming(&TimerInfoSend))//时间到，发送信息
        {
            Timer_startTiming(&TimerInfoSend,(uint16_t)strPDS.infoSendTime * 60);//重新计时
            if(isHalfSleep == 1)//处于半休眠
            {
                uint8_t cmd = 0x25;
                main_sendCmd(&cmd,4,(uint8_t *)&strPDS.msp430ID,0,0);
            }
            else if(isHalfSleep == 0)//不处于半休眠
            {
                //-----------------------光谱仪定时采集----------------------
                if(isFPGA_SpectrometerContinuousSend == 2)
                {
                    uint8_t cmd = 0x73;
                    FPGA_ReceiveSpectrometer(pFPGA_Spectrometer);
                    ATGM336H_getRMC(pATGM336H_GPS,&ATGM336H_GPSdataCount);
                    main_sendCmd(&cmd,ATGM336H_GPSdataCount+4096,pSpectrometerAndGpsBuff,0,0);
                }

                //------------------获取要发送的信息并计算长度-------------------
                if(strPDS.infoSendDetail & 0x80)//握手信息，长度为4
                {
                    pareCount += 4;
                }
                if(strPDS.infoSendDetail & 0x40)//GPS，长度ATGM336H_GPSdataCount
                {
//                    printfDBG("Get GPS",7);
                    ATGM336H_getRMC(pATGM336H_GPS,&ATGM336H_GPSdataCount);
                    pareCount += ATGM336H_GPSdataCount;
                }
                if(strPDS.infoSendDetail & 0x20)//陀螺仪，长度6
                {
//                    printfDBG("Get gyroscope",13);
                    ICM_Get_Accelerometer(&pICM_Accel[2],&pICM_Accel[1],&pICM_Accel[0]);
                    pareCount += 6;
                }
                if(strPDS.infoSendDetail & 0x10)//电池电量battery，长度1
                {
//                    printfDBG("Get batter",10);
                    battery_getVoltage(&battery_Voltage);
                    pareCount += 1;
                }
                if(strPDS.infoSendDetail & 0x08)//电源电压vbat，长度2
                {
//                    printfDBG("Get vbat",8);
                    vbat_GetVoltage(&vbat_Voltage);
                    pareCount += 2;
                }
                if(strPDS.infoSendDetail & 0x04)//离水状态，长度1
                {
//                    printfDBG("Get leaveWater",14);
                    lwater_isLeave(&isLeaveWater);
                    pareCount += 1;
                }
                if(strPDS.infoSendDetail & 0x02)//水质温度，长度4
                {
//                    printfDBG("Get BAT2U",9);
                    BAT2U_SenseCommand(&pBAT2U_Buff[1], &pBAT2U_Buff[0]);
                    pareCount += 4;
                }
                if(strPDS.infoSendDetail & 0x01)//设备信息，长度31
                {
                    pareCount += PDS_LEN;
                }
//                printfDBG("Get data finid",14);
                //-----------获取完了数据也得到了数据长度，开始发送到4G模块----------
                pareCount += 8;//总长度为参数长度+8
                crc += 0x55;
                USCI_A_UART_transmitData(WHGM5_USCI_BASE,0x55);
                crc += 0xcc;
                USCI_A_UART_transmitData(WHGM5_USCI_BASE,0xcc);
                crc += (uint8_t)pareCount;
                USCI_A_UART_transmitData(WHGM5_USCI_BASE,(uint8_t)pareCount);//命令长度是MSB，高位在低端，所以这里反过来
                crc += (uint8_t)(pareCount >> 8);
                USCI_A_UART_transmitData(WHGM5_USCI_BASE,(uint8_t)(pareCount >> 8));
                crc += 0x25;//0x40
                USCI_A_UART_transmitData(WHGM5_USCI_BASE,0x25);
                if(strPDS.infoSendDetail & 0x80)//握手信息，长度为4
                {
                    main_sendStrLen((uint8_t *)&strPDS.msp430ID,4,0,&crc);
                }
                if(strPDS.infoSendDetail & 0x40)//GPS，长度ATGM336H_RxBufferCount
                {
                    main_sendStrLen((uint8_t *)pATGM336H_GPS,ATGM336H_GPSdataCount,0,&crc);
                }
                if(strPDS.infoSendDetail & 0x20)//陀螺仪，长度6
                {
                    main_sendStrLen((uint8_t *)pICM_Accel,6,1,&crc);
                }
                if(strPDS.infoSendDetail & 0x10)//电池电量battery，长度1
                {
                    main_sendStrLen((uint8_t *)&battery_Voltage,1,1,&crc);
                }
                if(strPDS.infoSendDetail & 0x08)//电源电压vbat，长度2
                {
                    main_sendStrLen((uint8_t *)&vbat_Voltage,2,1,&crc);
                }
                if(strPDS.infoSendDetail & 0x04)//离水状态，长度1
                {
                    main_sendStrLen((uint8_t *)&isLeaveWater,1,1,&crc);
                }
                if(strPDS.infoSendDetail & 0x02)//水质温度，长度4
                {
                    main_sendStrLen((uint8_t *)&pBAT2U_Buff,4,1,&crc);
                }
                if(strPDS.infoSendDetail & 0x01)//设备信息，长度31
                {
                    main_sendStrLen((uint8_t *)&strPDS,PDS_LEN,0,&crc);
                }
                USCI_A_UART_transmitData(WHGM5_USCI_BASE,crc);
                USCI_A_UART_transmitData(WHGM5_USCI_BASE,0x00);
                USCI_A_UART_transmitData(WHGM5_USCI_BASE,0x00);
            }
        }
    }
//-----------------------------检查电源电压-----------------------------------
    if(TimerVbatCheck.flag & TIMER_STR_SECOND_CHRON_FLAG_RUNING)
    {
        uint8_t cmd;
        uint8_t vbat32pare[7];
        if(Timer_checkoutTiming(&TimerVbatCheck))
        {
            printfDBG("Check Vbat start",16);
            Timer_startTiming(&TimerVbatCheck,strPDS.lowPoewrCheackInterval);
            vbat_GetVoltage(&vbat_Voltage);
            if(strPDS.lowPowerThreshold > vbat_Voltage)//如果电压低于阈值
            {
                printfDBG("Vbat less than threshold",24);
                if(!(TimerLowPowMode.flag & TIMER_STR_SECOND_CHRON_FLAG_RUNING))
                {
                    printfDBG("Is not in Low Power mode now",28);
                    cmd = 0x37;
                    vbat32pare[0] = strPDS.lowPowerEnable;
                    vbat32pare[1] = strPDS.lowPowerSleep;
                    vbat32pare[2] = (uint8_t)((vbat_Voltage & 0xff00) >> 8);
                    vbat32pare[3] = (uint8_t)(vbat_Voltage & 0xff);
                    vbat32pare[4] = (uint8_t)((strPDS.lowPoewrCheackInterval & 0xff00) >> 8);
                    vbat32pare[5] = (uint8_t)(strPDS.lowPoewrCheackInterval & 0xff);
                    vbat32pare[6] = strPDS.lowPowerSleepInterval;
                    main_sendCmd(&cmd,7,(uint8_t *)&vbat32pare,0,0);
                    if(strPDS.lowPowerEnable)//如果使能了4G关断
                    {
                        uint16_t timerNow;
                        printfDBG("Low Power mode has enabled,enter Low Power mode now",51);
                        __delay_cycles(MSP430_FREQUENCY);//延迟一秒让4G模块的最后一条信息发送完毕，避免还未发送完毕就进入了低功耗模式
                        Timer_startTiming(&TimerLowPowMode,strPDS.lowPowerSleep*60 - 20);//开始计时n*60-20秒，预留20秒初始化被重新打开的模块
                        Timer_closeTiming(&TimerInfoSend);
                        printfDBG("Enter Low Power mode now",24);
                        msp430_LowPower_Enter();//关闭各种模块
                        timerNow = TimerS.timer;//记录当前秒表时间
                        __bis_SR_register(LPM0_bits+GIE);//单片机进入低功耗模式,十分钟后回来这里接着运行

                        printfDBG("Leave Low Power mode now",24);
                        Timer_closeTiming(&TimerLowPowMode);
                        msp430_LowPower_Exit();//打开各种模块
                        battery_Init();
                        ATGM336H_Init();
                        ICM_IIC_Init();
                        TimerS.timer = timerNow;//让计时器秒表回到休眠前的时间
                        printfDBG("Reinit gyroscope finish",23);
                        Timer_startTiming(&TimerVbatCheck,strPDS.lowPowerSleepInterval*60);//n*60秒后再次检查电压，如果到那时电源电压依旧低于阈值，则再次进入低功耗模式
                        Timer_startTiming(&TimerInfoSend,1);//1秒后开始发送设备信息
                    }
                }
            }
            printfDBG("Check Vbat finish",17);
        }
    }
}

